package com.coconet.gas.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.coconet.gas.dao.SysRoleMapper;
import com.coconet.gas.dao.SysUserMapper;
import com.coconet.gas.dao.SysUserRoleMapper;
import com.coconet.gas.jwt.vo.JwtTokenUtil;
import com.coconet.gas.service.SysUserService;
import com.coconet.gas.until.ConvertVoToMap;
import com.coconet.gas.vo.dw.SysRole;
import com.coconet.gas.vo.dw.SysUser;
import com.coconet.gas.vo.dw.SysUserRole;
import com.coconet.gas.vo.dw.st.CommonFy;
import com.coconet.gas.vo.request.UserAndRoleAndCompany;
import com.coconet.gas.vo.request.UserAndRoleid;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import tk.mybatis.mapper.entity.Example;
import tk.mybatis.mapper.entity.Example.Criteria;

import javax.annotation.Resource;
import java.util.*;

@Service
public class SysUserServiceImpl extends ConvertVoToMap<SysUser> implements SysUserService {

    @Autowired
    private AuthenticationManager authenticationManager;
    @Autowired
    private JwtTokenUtil jwtTokenUtil;
    @Resource
    private SysUserMapper sumapper;
    @Resource
    private SysUserRoleMapper surmapperl;
    /*@Resource
    private SysCompanyMapper scmapper;

    @Resource
    private SysCompanyRoleMapper scrsumapper;*/

    @Resource
    private SysRoleMapper srmapper;

    @Override
    public String login(String username, String password) {
        // TODO Auto-generated method stub
        UsernamePasswordAuthenticationToken upToken = new UsernamePasswordAuthenticationToken(username, password);
        Authentication authentication = authenticationManager.authenticate(upToken);
        SecurityContextHolder.getContext().setAuthentication(authentication);
        SysUser user = sumapper.selectByPrimaryKey(username);
        return jwtTokenUtil.generateToken(user);
    }

    @Override
    public String refreshToken(String oldToken) {
        // TODO Auto-generated method stub
        String token = oldToken.substring("Bearer ".length());
        if (!jwtTokenUtil.isTokenExpired(token)) {
            return jwtTokenUtil.refreshToken(token);
        }
        return "error";

    }

    @Override
    @Transactional
    public void add(UserAndRoleAndCompany vo) {
        // TODO Auto-generated method stub
        BCryptPasswordEncoder bCryptPasswordEncoder = new BCryptPasswordEncoder();
        String password = bCryptPasswordEncoder.encode(vo.getPassword());
        vo.setPassword(password);
        sumapper.insertSelective(vo);
        for (SysRole sy : vo.getChildRole()) {
            SysUserRole sur = new SysUserRole();
            sur.setRoleId(sy.getId());
            sur.setUserId(vo.getUsername());
            sur.setId(UUID.randomUUID().toString().replace("-", "").toLowerCase());
            surmapperl.insertSelective(sur);
        }

    }

    @Override
    public PageInfo<Map<String, Object>> findByRole(List<String> authorities, CommonFy cfy) {
        Map<String, Object> map = JSONObject.parseObject(cfy.getMapStr());
        PageHelper.startPage(cfy.getCurrentPage(), cfy.getPageSize());
        if (authorities.contains("vadmin")) {
            // rootMenu = scmapper.selectAll();
            List<SysUser> rootMenu = new ArrayList<>();
            Example exUser = new Example(SysUser.class);
            Criteria criteria = exUser.createCriteria();
            if (map != null && map.size() > 0) {
                map.forEach((key, value) -> {
                    criteria.andLike(key, "%" + value + "%");
                });// 把需要的所有模糊搜索全部加上
                rootMenu = sumapper.selectByExample(exUser);
                for (int i = 0; i < rootMenu.size(); i++) {
                    if (rootMenu.get(i).getRole().equals("vadmin")) {
                        rootMenu.remove(i);
                    }
                }
            } else {
                rootMenu = sumapper.selectAll();
                for (int i = 0; i < rootMenu.size(); i++) {
                    if (rootMenu.get(i).getRole().equals("vadmin")) {
                        rootMenu.remove(i);
                    }
                }
            }

           // List<Map<String, Object>> wrap = new SysuserControllerWrapper(CVTMLi(rootMenu)).wrap();
            //PageInfo<Map<String, Object>> pageInfo = new PageInfo<Map<String, Object>>(wrap);
            PageInfo<Map<String, Object>> pageInfo = null;
            return pageInfo;
        } else if (authorities.contains("1")) {/*
            List<SysCompany> rootMenu = scmapper.selectAll();
            // 查找非管理员 所有的管理权限
            UserDetails userDetails = (UserDetails) SecurityContextHolder.getContext().getAuthentication()
                    .getPrincipal();
            SysUser vo = sumapper.selectByPrimaryKey(userDetails.getUsername());
            SysCompany sc = scmapper.selectByPrimaryKey(vo.getCid());
            // 先找到所有的一级菜单
            // 为一级菜单设置子菜单，getChild是递归调用的

            List<String> cidLi = MenuUtil.getcid(sc.getId(), rootMenu);
            // 查询所有角色

            Example exampleCompany = new Example(SysUser.class);
            Criteria criteria = exampleCompany.createCriteria();
            criteria.andIn("cid", cidLi);
            if (map != null && map.size() > 0) {
                map.forEach((key, value) -> {
                    criteria.andLike(key, "%" + value + "%");
                });// 把需要的所有模糊搜索全部加上
            }
            List<SysUser> scList = sumapper.selectByExample(exampleCompany);
            List<SysUser> uList = new ArrayList<>();
            for (int i = 0; i < scList.size(); i++) {
                String role = scList.get(i).getRole();
                if (!authorities.contains(role)) {
                    uList.add(scList.get(i));
                }
            }
            List<Map<String, Object>> wrap = new SysuserControllerWrapper(CVTMLi(uList)).wrap();
            PageInfo<Map<String, Object>> pageInfo = new PageInfo<Map<String, Object>>(wrap);
            return pageInfo;*/
            return null;

        } /*else {

            Example exampleRole = new Example(SysRole.class);
            exampleRole.createCriteria().andIn("roleName", authorities);
            List<SysRole> srList = srmapper.selectByExample(exampleRole);

            // companyROle
            List<String> rid = srList.stream().map(n -> n.getId()).collect(Collectors.toList());
            Example exampleCompanyRole = new Example(SysCompanyRole.class);
            exampleCompanyRole.createCriteria().andIn("rid", rid);
            List<SysCompanyRole> scrList = scrsumapper.selectByExample(exampleCompanyRole);

            // 查询 最后 公司集合
            List<String> cidLi = scrList.stream().map(n -> n.getCid()).collect(Collectors.toList());
            if (cidLi.size() == 0) {
                return null;
            }
            Example exampleCompany = new Example(SysUser.class);
            Criteria criteria = exampleCompany.createCriteria();
            criteria.andIn("cid", cidLi);
            if (map != null && map.size() > 0) {
                map.forEach((key, value) -> {
                    criteria.andLike(key, "%" + value + "%");
                });// 把需要的所有模糊搜索全部加上
            }
            List<SysUser> scList = sumapper.selectByExample(exampleCompany);
            // 查询公司 在查询 角色
            List<SysUser> uList = new ArrayList<>();
            for (int i = 0; i < scList.size(); i++) {
                String role = scList.get(i).getRole();
                if (!authorities.contains(role) && !role.equals("admin")) {
                    uList.add(scList.get(i));
                }
            }
            List<Map<String, Object>> wrap = new SysuserControllerWrapper(CVTMLi(uList)).wrap();
            PageInfo<Map<String, Object>> pageInfo = new PageInfo<Map<String, Object>>(wrap);
            return pageInfo;

        }*/

        // menuList.forEach(e->e.setChildren(MenuUtil.getChild(e.getId(),rootMenu)));
        //
        // Map<String, Object> jsonMap = new HashMap<>();
        // jsonMap.put("menu", menuList);
        return null;
    }

    @Override
    @Transactional
    public void addUser(UserAndRoleid user) {
        // TODO Auto-generated method stub
        UserDetails userDetails = (UserDetails) SecurityContextHolder.getContext().getAuthentication().getPrincipal();

        BCryptPasswordEncoder bCryptPasswordEncoder = new BCryptPasswordEncoder();
        user.setPassword(bCryptPasswordEncoder.encode(user.getPassword()));
        user.setCreateTime(new Date());
        user.setCreateBy(userDetails.getUsername());
        user.setStatus(0);
        SysRole sysRole = new SysRole();
        sysRole.setId(user.getRoleid());
        SysRole sysRole1 = srmapper.selectOne(sysRole);
        String roleName = sysRole1.getRoleName();
        user.setRole(roleName);
        sumapper.insertSelective(user);
        SysUserRole sur = new SysUserRole();
        sur.setRoleId(user.getRoleid());
        sur.setUserId(user.getUsername());
        sur.setId(UUID.randomUUID().toString().replaceAll("-", ""));
        surmapperl.insertSelective(sur);

    }

    @Override
    @Transactional
    public void updateUser(UserAndRoleid user) {
        // TODO Auto-generated method stub
        UserDetails userDetails = (UserDetails) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        if (user.getPassword() != null && !user.getPassword().equals("")) {
            BCryptPasswordEncoder bCryptPasswordEncoder = new BCryptPasswordEncoder();
            user.setPassword(bCryptPasswordEncoder.encode(user.getPassword()));
            if (!user.getUsername().equals(user.getOldName())) {
                sumapper.updateUsernameAndPassword(user.getUsername(), user.getPassword(), user.getOldName());
                SysUser sysUser = new SysUser();
                sysUser.setUsername(user.getUsername());
                sysUser.setUpdateTime(new Date());
                sysUser.setUpdateBy(userDetails.getUsername());
                sysUser.setStatus(0);
                if (user.getRoleid()!=null && !user.getRoleid().equals("")){
                    user.setRole(srmapper.selectByPrimaryKey(user.getRoleid()).getRoleName());
                }
                sumapper.updateByPrimaryKeySelective(sysUser);
            } else if (user.getUsername().equals(user.getOldName())) {
                user.setUpdateTime(new Date());
                user.setUpdateBy(userDetails.getUsername());
                user.setStatus(0);
                if (user.getRoleid()!=null && !user.getRoleid().equals("")){
                    user.setRole(srmapper.selectByPrimaryKey(user.getRoleid()).getRoleName());
                }
                sumapper.updateByPrimaryKeySelective(user);
            }

        }
        if (!user.getUsername().equals(user.getOldName())) {
            sumapper.updateUsername(user.getUsername(), user.getOldName());
            SysUser sysUser = new SysUser();
            sysUser.setUsername(user.getUsername());
            sysUser.setUpdateTime(new Date());
            sysUser.setUpdateBy(userDetails.getUsername());
            sysUser.setStatus(0);
            if (user.getRoleid()!=null && !user.getRoleid().equals("")){
                user.setRole(srmapper.selectByPrimaryKey(user.getRoleid()).getRoleName());
            }
            sumapper.updateByPrimaryKeySelective(sysUser);
        } else if (user.getUsername().equals(user.getOldName())) {
            user.setUpdateTime(new Date());
            user.setUpdateBy(userDetails.getUsername());
            user.setStatus(0);
            if (user.getRoleid()!=null && !user.getRoleid().equals("")){
                user.setRole(srmapper.selectByPrimaryKey(user.getRoleid()).getRoleName());
            }
            sumapper.updateByPrimaryKeySelective(user);
        }


        if (user.getRoleid() != null && !user.getRoleid().equals("")) {
            SysUserRole sur = new SysUserRole();
            sur.setUserId(user.getUsername());
            surmapperl.selectOne(sur);
            sur.setRoleId(user.getRoleid());
            //sur.setUserId(user.getUsername());
            surmapperl.updateByUsername(sur);
        }

    }

    @Override
    //@Cacheable(value = "quartz", keyGenerator = "CacheKeyGenerator")
    public List<SysUser> seletUser(SysUser usr) {
        return sumapper.select(usr);
    }

    @Override
    //@CacheEvict(value = "quartz", keyGenerator = "CacheKeyGenerator")
    public void delet(SysUser usr) {
        sumapper.delete(usr);
    }


}
